#include "stdint.h"
#include "string.h"
#include "main.h"
#include "LsdPublicUse.h"
#include "LsdMem.h"
#include "aes128.h"
#include "LsdAES.h"
#include "base64.h"
#include "bsp_usart.h"
//#include "LsdEEPROM.h"
#define KEY_SIZE       16
#define AES_IV_SIZE    16
static AES_CTX context ;
/*******************************************************************************/
/*****************************加密***********************************************/
/*******************************************************************************/
//HEX用AES加密成hex 再转成base64      如果是蓝牙再转成ASCii//这里代码里面没有体现可以在具体代码中实现
TypeBuffDef * OnHexToAES128CBC(uint8_t *inbuff, uint16_t inlen, const char *aes_key, const char *aes_iv)
{
	static TypeBuffDef aesOut = {NULL, 0};
	//再解密 先初始化接口
	uint16_t newLen = (inlen / 16) * 16 + 16;
	//把inbuff进行一下填充
	uint8_t *newInBuff = pvPortMalloc(newLen + 1);
	memset(newInBuff, 0, newLen + 1);
	memcpy(newInBuff, inbuff, inlen);
	
	//分配一个新的临时缓存区
	if(aesOut.buff)
	{
		vPortFree(aesOut.buff);
	}
	aesOut.len = newLen;
	aesOut.buff = pvPortMalloc(newLen + 1);
	memset(aesOut.buff, 0, newLen + 1);
	
	//初始化接口
	memset(&context, 0, sizeof(AES_CTX));//初始化数据区
	AES_set_key(&context, aes_key, aes_iv, AES_MODE_128);//@7 设置秘钥
	//开始转换
	
  AES_cbc_encrypt(&context, newInBuff, aesOut.buff, newLen);

	vPortFree(newInBuff);//释放newInBuff

	return &aesOut;
}
//把AES加密后的数据转化为base64
//加密
TypeBuffDef *OnHexDataToAES128CBCToBase64(uint8_t *inbuff, uint16_t inlen) 
{
			static TypeBuffDef base64Out = {NULL, 0};
			TypeBuffDef * aesOut= OnHexToAES128CBC(inbuff, inlen, DevGPRSInfo.AES_KEY, DevGPRSInfo.AES_KEY);
      //转换成base64
			if(base64Out.buff)
			{
				vPortFree(base64Out.buff);
			} 
			base64Out.len = b64_encode_len(aesOut->buff,aesOut->len);//@7计算出转化成base64后的长度
			base64Out.buff = pvPortMalloc(base64Out.len+1);
			memset(base64Out.buff,0,base64Out.len+1);
			base64Out.len = b64_encode(aesOut->buff,aesOut->len,(char *)base64Out.buff);
			
			return &base64Out;
}
/*******************************************************************************/
/*****************************解密***********************************************/
/*******************************************************************************/
//
TypeBuffDef *OnCtrlAES128CBCToData(uint8_t *inbuff, uint16_t inlen, const char *aes_key, const char *aes_iv)  //hex解密成hex
{
	static TypeBuffDef strOut = {NULL, 0};
	//再解密 先初始化接口
	memset(&context, 0, sizeof(AES_CTX));//初始化数据区
	AES_set_key(&context, aes_key, aes_iv, AES_MODE_128);
	//分配一段临时内存
	if(strOut.buff)
	{
		vPortFree(strOut.buff);
	}
	strOut.len = inlen;
	strOut.buff = pvPortMalloc(strOut.len + 1);
	memset(strOut.buff, 0, strOut.len + 1);
	AES_convert_key(&context);
  AES_cbc_decrypt(&context, inbuff, strOut.buff, strOut.len);
	//把后面补的0全部减去
	while(strOut.len && !strOut.buff[strOut.len - 1]) strOut.len--;
	return &strOut;
}

//解密 
TypeBuffDef * OnBase64ToAES128CBCToHex(uint8_t *inbuff)  //base64解密成hex
{
	  
	  TypeBuffDef aesOut= {NULL,0};
		uint16_t len = strlen((char *)inbuff);
		aesOut.buff = pvPortMalloc(len + 1);
		memset(aesOut.buff,0,len+1);
		aesOut.len = b64_decode((char *)inbuff, aesOut.buff);	
		TypeBuffDef *buff=OnCtrlAES128CBCToData(aesOut.buff, aesOut.len, DevGPRSInfo.AES_KEY, DevGPRSInfo.AES_KEY);  //将密文hex 解密成 明文hex
		vPortFree(aesOut.buff);
		return buff;
}


void AESTest(void)
{
	
	  TypeBuffDef *aesOut;
	  uint8_t inbuff[3] = {0x22,0X11,0X11};
		aesOut =OnHexDataToAES128CBCToBase64(inbuff, 3);
		print_debug("%s\r\n",aesOut->buff);
    aesOut= OnBase64ToAES128CBCToHex(aesOut->buff);
		print_debug("aesOut->buff:%d\r\n",aesOut->buff[0]);
		print_debug("aesOut->len:%d\r\n",aesOut->len);
}

//解密

/*
unsigned int b64_decode(char *code, unsigned char *retbuff)  
{  
//根据base64表，以字符找到对应的十进制数据  
  static const unsigned char table[]={0,0,0,0,0,0,0,0,0,0,0,0,
    		 0,0,0,0,0,0,0,0,0,0,0,0,
    		 0,0,0,0,0,0,0,0,0,0,0,0,
    		 0,0,0,0,0,0,0,62,0,0,0,
    		 63,52,53,54,55,56,57,58,
    		 59,60,61,0,0,0,0,0,0,0,0,
    		 1,2,3,4,5,6,7,8,9,10,11,12,
    		 13,14,15,16,17,18,19,20,21,
    		 22,23,24,25,0,0,0,0,0,0,26,
    		 27,28,29,30,31,32,33,34,35,
    		 36,37,38,39,40,41,42,43,44,
    		 45,46,47,48,49,50,51
    	       };  
    unsigned int len;  
    unsigned int str_len;    
    int i,j;  
  
//计算解码后的字符串长度  
    len=strlen(code);  
//判断编码后的字符串后是否有=  
    if(strstr(code,"=="))  
        str_len=len/4*3-2;  
    else if(strstr(code,"="))  
        str_len=len/4*3-1;  
    else  
        str_len=len/4*3;  
  
    retbuff[str_len]='\0';  
  
//以4个字符为一位进行解码  
    for(i=0,j=0;i < len-2;j+=3,i+=4)  
    {  
        retbuff[j]=((unsigned char)table[code[i]])<<2 | (((unsigned char)table[code[i+1]])>>4); //取出第一个字符对应base64表的十进制数的前6位与第二个字符对应base64表的十进制数的后2位进行组合  
        retbuff[j+1]=(((unsigned char)table[code[i+1]])<<4) | (((unsigned char)table[code[i+2]])>>2); //取出第二个字符对应base64表的十进制数的后4位与第三个字符对应bas464表的十进制数的后4位进行组合  
        retbuff[j+2]=(((unsigned char)table[code[i+2]])<<6) | ((unsigned char)table[code[i+3]]); //取出第三个字符对应base64表的十进制数的后2位与第4个字符进行组合  
    }  
    return str_len;  
}
//解密
TypeBuffDef *OnCtrlAES128CBCToData(uint8_t *inbuff, uint16_t inlen, const char *aes_key, const char *aes_iv)
{
	static TypeBuffDef strOut = {NULL, 0};
	//再解密 先初始化接口
	memset(&context, 0, sizeof(AES_CTX));//初始化数据区
	AES_set_key(&context, aes_key, aes_iv, AES_MODE_128);
	//分配一段临时内存
	if(strOut.buff)
	{
		vPortFree(strOut.buff);
	}
	strOut.len = inlen;
	strOut.buff = pvPortMalloc(strOut.len + 1);
	memset(strOut.buff, 0, strOut.len + 1);
	AES_convert_key(&context);
    AES_cbc_decrypt(&context, inbuff, strOut.buff, strOut.len);
	//把后面补的0全部减去
	while(strOut.len && !strOut.buff[strOut.len - 1]) strOut.len--;
	return &strOut;
}

//解密
TypeBuffDef *OnAES128CBCToData(uint8_t *inbuff)
{
	uint8_t *buff = NULL;
	uint16_t len = strlen((char *)inbuff);
	//先解码成str
	uint16_t newLen = len;
	buff = pvPortMalloc(newLen + 1);
	memset(buff, 0, newLen + 1);
	newLen = b64_decode((char *)inbuff, buff);
	// for(uint8_t i=0;i<newLen;i++)
	// {
	// 		print_debug("buff[i]:%x\r\n",buff[i]);
	// }
	
	return OnCtrlAES128CBCToData(buff, newLen, DevGPRSInfo.AES_KEY, DevGPRSInfo.AES_KEY);
}
*/
